; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=jump-threading < %s | FileCheck %s

%struct.ham = type { i8, i8, i16, i32 }
%struct.zot = type { ptr }
%struct.quux.0 = type { %struct.wombat }
%struct.wombat = type { %struct.zot }

@global = external global ptr, align 8
@global.1 = external constant ptr

declare i32 @wombat.2()

define void @blam() {
; CHECK-LABEL: @blam(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr undef, align 4
; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0
; CHECK-NEXT:    br i1 [[TMP1]], label [[BB11:%.*]], label [[BB2:%.*]]
; CHECK:       bb2:
; CHECK-NEXT:    [[TMP3:%.*]] = tail call i32 @wombat.2()
; CHECK-NEXT:    switch i32 [[TMP3]], label [[BB10:%.*]] [
; CHECK-NEXT:    i32 0, label [[BB7:%.*]]
; CHECK-NEXT:    i32 1, label [[BB10]]
; CHECK-NEXT:    i32 2, label [[BB10]]
; CHECK-NEXT:    i32 3, label [[BB11]]
; CHECK-NEXT:    ]
; CHECK:       bb7:
; CHECK-NEXT:    [[TMP6:%.*]] = tail call i32 @wombat.2()
; CHECK-NEXT:    br label [[BB11]]
; CHECK:       bb10:
; CHECK-NEXT:    ret void
; CHECK:       bb11:
; CHECK-NEXT:    ret void
;
bb:
  %tmp = load i32, ptr undef
  %tmp1 = icmp eq i32 %tmp, 0
  br i1 %tmp1, label %bb11, label %bb2

bb2:
  %tmp3 = tail call i32 @wombat.2()
  switch i32 %tmp3, label %bb4 [
    i32 0, label %bb5
    i32 1, label %bb7
    i32 2, label %bb7
    i32 3, label %bb11
  ]

bb4:
  br label %bb7

bb5:
  %tmp6 = tail call i32 @wombat.2()
  br label %bb7

bb7:
  %tmp8 = phi i32 [ 0, %bb5 ], [ 1, %bb4 ], [ 2, %bb2 ], [ 2, %bb2 ]
  %tmp9 = icmp eq i32 %tmp8, 0
  br i1 %tmp9, label %bb11, label %bb10

bb10:
  ret void

bb11:
  ret void
}

define void @spam(ptr %arg) {
; CHECK-LABEL: @spam(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    [[TMP:%.*]] = load i8, ptr undef, align 8
; CHECK-NEXT:    switch i8 [[TMP]], label [[BB11:%.*]] [
; CHECK-NEXT:    i8 1, label [[BB11]]
; CHECK-NEXT:    i8 2, label [[BB11]]
; CHECK-NEXT:    i8 3, label [[BB1:%.*]]
; CHECK-NEXT:    i8 4, label [[BB1]]
; CHECK-NEXT:    ]
; CHECK:       bb1:
; CHECK-NEXT:    br label [[BB2:%.*]]
; CHECK:       bb2:
; CHECK-NEXT:    [[TMP3:%.*]] = phi i32 [ 0, [[BB1]] ], [ [[TMP3]], [[BB8:%.*]] ]
; CHECK-NEXT:    br label [[BB4:%.*]]
; CHECK:       bb4:
; CHECK-NEXT:    [[TMP5:%.*]] = load i8, ptr undef, align 8
; CHECK-NEXT:    switch i8 [[TMP5]], label [[BB11]] [
; CHECK-NEXT:    i8 0, label [[BB11]]
; CHECK-NEXT:    i8 1, label [[BB10:%.*]]
; CHECK-NEXT:    i8 2, label [[BB10]]
; CHECK-NEXT:    i8 3, label [[BB8]]
; CHECK-NEXT:    i8 4, label [[BB8]]
; CHECK-NEXT:    ]
; CHECK:       bb8:
; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq ptr undef, [[ARG:%.*]]
; CHECK-NEXT:    br i1 [[TMP9]], label [[BB10]], label [[BB2]]
; CHECK:       bb10:
; CHECK-NEXT:    switch i32 [[TMP3]], label [[BB4]] [
; CHECK-NEXT:    i32 0, label [[BB16:%.*]]
; CHECK-NEXT:    i32 1, label [[BB11]]
; CHECK-NEXT:    i32 2, label [[BB12:%.*]]
; CHECK-NEXT:    ]
; CHECK:       bb11:
; CHECK-NEXT:    unreachable
; CHECK:       bb12:
; CHECK-NEXT:    [[TMP13:%.*]] = load ptr, ptr undef, align 8
; CHECK-NEXT:    br label [[BB16]]
; CHECK:       bb16:
; CHECK-NEXT:    [[TMP15:%.*]] = phi ptr [ [[TMP13]], [[BB12]] ], [ null, [[BB10]] ]
; CHECK-NEXT:    [[TMP17:%.*]] = load i8, ptr undef, align 8
; CHECK-NEXT:    switch i8 [[TMP17]], label [[BB11]] [
; CHECK-NEXT:    i8 0, label [[BB11]]
; CHECK-NEXT:    i8 11, label [[BB23:%.*]]
; CHECK-NEXT:    i8 12, label [[BB23]]
; CHECK-NEXT:    ]
; CHECK:       bb23:
; CHECK-NEXT:    [[TMP21:%.*]] = load ptr, ptr undef, align 8
; CHECK-NEXT:    [[TMP24:%.*]] = icmp eq ptr [[TMP21]], null
; CHECK-NEXT:    br i1 [[TMP24]], label [[BB37:%.*]], label [[BB25:%.*]]
; CHECK:       bb25:
; CHECK-NEXT:    [[TMP26:%.*]] = icmp eq ptr [[TMP15]], null
; CHECK-NEXT:    br i1 [[TMP26]], label [[BB41_THREAD:%.*]], label [[BB27:%.*]]
; CHECK:       bb27:
; CHECK-NEXT:    [[TMP28:%.*]] = load ptr, ptr undef, align 8
; CHECK-NEXT:    [[TMP29:%.*]] = icmp eq ptr [[TMP28]], [[TMP21]]
; CHECK-NEXT:    br i1 [[TMP29]], label [[BB41_THREAD]], label [[BB30:%.*]]
; CHECK:       bb30:
; CHECK-NEXT:    [[TMP32_PR:%.*]] = load i8, ptr undef, align 8
; CHECK-NEXT:    br label [[BB31:%.*]]
; CHECK:       bb31:
; CHECK-NEXT:    [[TMP32:%.*]] = phi i8 [ [[TMP32]], [[BB31]] ], [ [[TMP32_PR]], [[BB30]] ]
; CHECK-NEXT:    [[TMP33:%.*]] = icmp eq i8 [[TMP32]], 0
; CHECK-NEXT:    br i1 [[TMP33]], label [[BB31]], label [[BB37]]
; CHECK:       bb37:
; CHECK-NEXT:    [[TMP36:%.*]] = phi i1 [ false, [[BB23]] ], [ true, [[BB31]] ]
; CHECK-NEXT:    [[TMP38:%.*]] = icmp eq ptr [[TMP15]], null
; CHECK-NEXT:    br i1 [[TMP38]], label [[BB39:%.*]], label [[BB41:%.*]]
; CHECK:       bb39:
; CHECK-NEXT:    [[TMP364:%.*]] = phi i1 [ [[TMP36]], [[BB37]] ]
; CHECK-NEXT:    [[TMP40:%.*]] = load ptr, ptr @global, align 8
; CHECK-NEXT:    br i1 [[TMP364]], label [[BB41_THREAD]], label [[BB41_THREAD]]
; CHECK:       bb41:
; CHECK-NEXT:    [[TMP363:%.*]] = phi i1 [ [[TMP36]], [[BB37]] ]
; CHECK-NEXT:    br i1 [[TMP363]], label [[BB41_THREAD]], label [[BB41_THREAD]]
; CHECK:       bb41.thread:
; CHECK-NEXT:    [[TMP0:%.*]] = phi ptr [ undef, [[BB41]] ], [ undef, [[BB39]] ], [ undef, [[BB39]] ], [ undef, [[BB41]] ], [ undef, [[BB27]] ], [ undef, [[BB25]] ]
; CHECK-NEXT:    ret void
;
bb:
  %tmp = load i8, ptr undef, align 8
  switch i8 %tmp, label %bb11 [
    i8 1, label %bb11
    i8 2, label %bb11
    i8 3, label %bb1
    i8 4, label %bb1
  ]

bb1:
  br label %bb2

bb2:
  %tmp3 = phi i32 [ 0, %bb1 ], [ %tmp3, %bb8 ]
  br label %bb4

bb4:
  %tmp5 = load i8, ptr undef, align 8
  switch i8 %tmp5, label %bb11 [
    i8 0, label %bb11
    i8 1, label %bb10
    i8 2, label %bb10
    i8 3, label %bb6
    i8 4, label %bb6
  ]

bb6:
  br label %bb7

bb7:
  br i1 undef, label %bb8, label %bb10

bb8:
  %tmp9 = icmp eq ptr undef, %arg
  br i1 %tmp9, label %bb10, label %bb2

bb10:
  switch i32 %tmp3, label %bb4 [
    i32 0, label %bb14
    i32 1, label %bb11
    i32 2, label %bb12
  ]

bb11:
  unreachable

bb12:
  %tmp13 = load ptr, ptr undef
  br label %bb14

bb14:
  %tmp15 = phi ptr [ %tmp13, %bb12 ], [ null, %bb10 ]
  br label %bb16

bb16:
  %tmp17 = load i8, ptr undef, align 8
  switch i8 %tmp17, label %bb11 [
    i8 0, label %bb11
    i8 11, label %bb18
    i8 12, label %bb18
  ]

bb18:
  br label %bb19

bb19:
  br label %bb20

bb20:
  %tmp21 = load ptr, ptr undef
  switch i8 undef, label %bb22 [
    i8 0, label %bb4
    i8 11, label %bb10
    i8 12, label %bb10
  ]

bb22:
  br label %bb23

bb23:
  %tmp24 = icmp eq ptr %tmp21, null
  br i1 %tmp24, label %bb35, label %bb25

bb25:
  %tmp26 = icmp eq ptr %tmp15, null
  br i1 %tmp26, label %bb34, label %bb27

bb27:
  %tmp28 = load ptr, ptr undef
  %tmp29 = icmp eq ptr %tmp28, %tmp21
  br i1 %tmp29, label %bb35, label %bb30

bb30:
  br label %bb31

bb31:
  %tmp32 = load i8, ptr undef, align 8
  %tmp33 = icmp eq i8 %tmp32, 0
  br i1 %tmp33, label %bb31, label %bb34

bb34:
  br label %bb35

bb35:
  %tmp36 = phi i1 [ true, %bb34 ], [ false, %bb23 ], [ true, %bb27 ]
  br label %bb37

bb37:
  %tmp38 = icmp eq ptr %tmp15, null
  br i1 %tmp38, label %bb39, label %bb41

bb39:
  %tmp40 = load ptr, ptr @global
  br label %bb41

bb41:
  %tmp42 = select i1 %tmp36, ptr undef, ptr undef
  ret void
}

declare i32 @foo(...)

define void @zot() align 2 personality ptr @foo {
; CHECK-LABEL: @zot(
; CHECK-NEXT:  bb:
; CHECK-NEXT:    invoke void @bar()
; CHECK-NEXT:    to label [[BB1:%.*]] unwind label [[BB3:%.*]]
; CHECK:       bb1:
; CHECK-NEXT:    invoke void @bar()
; CHECK-NEXT:    to label [[BB2:%.*]] unwind label [[BB4:%.*]]
; CHECK:       bb2:
; CHECK-NEXT:    invoke void @bar()
; CHECK-NEXT:    to label [[BB6:%.*]] unwind label [[BB17:%.*]]
; CHECK:       bb3:
; CHECK-NEXT:    [[TMP:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT:    catch ptr @global.1
; CHECK-NEXT:    catch ptr null
; CHECK-NEXT:    unreachable
; CHECK:       bb4:
; CHECK-NEXT:    [[TMP5:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT:    catch ptr @global.1
; CHECK-NEXT:    catch ptr null
; CHECK-NEXT:    unreachable
; CHECK:       bb6:
; CHECK-NEXT:    invoke void @bar()
; CHECK-NEXT:    to label [[BB7:%.*]] unwind label [[BB19:%.*]]
; CHECK:       bb7:
; CHECK-NEXT:    invoke void @bar()
; CHECK-NEXT:    to label [[BB10:%.*]] unwind label [[BB8:%.*]]
; CHECK:       bb8:
; CHECK-NEXT:    [[TMP9:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    catch ptr @global.1
; CHECK-NEXT:    catch ptr null
; CHECK-NEXT:    unreachable
; CHECK:       bb10:
; CHECK-NEXT:    [[TMP11:%.*]] = load ptr, ptr undef, align 8
; CHECK-NEXT:    [[TMP12:%.*]] = invoke i32 [[TMP11]](ptr nonnull undef)
; CHECK-NEXT:    to label [[BB13:%.*]] unwind label [[BB21:%.*]]
; CHECK:       bb13:
; CHECK-NEXT:    invoke void @bar()
; CHECK-NEXT:    to label [[BB14:%.*]] unwind label [[BB30:%.*]]
; CHECK:       bb14:
; CHECK-NEXT:    [[TMP15:%.*]] = load ptr, ptr undef, align 8
; CHECK-NEXT:    [[TMP16:%.*]] = invoke i32 [[TMP15]](ptr nonnull undef)
; CHECK-NEXT:    to label [[BB26:%.*]] unwind label [[BB30_THREAD:%.*]]
; CHECK:       bb17:
; CHECK-NEXT:    [[TMP18:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT:    catch ptr @global.1
; CHECK-NEXT:    catch ptr null
; CHECK-NEXT:    unreachable
; CHECK:       bb19:
; CHECK-NEXT:    [[TMP20:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT:    catch ptr @global.1
; CHECK-NEXT:    catch ptr null
; CHECK-NEXT:    unreachable
; CHECK:       bb21:
; CHECK-NEXT:    [[TMP22:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT:    catch ptr @global.1
; CHECK-NEXT:    catch ptr null
; CHECK-NEXT:    unreachable
; CHECK:       bb26:
; CHECK-NEXT:    [[TMP27:%.*]] = load ptr, ptr undef, align 8
; CHECK-NEXT:    [[TMP28:%.*]] = invoke i32 [[TMP27]](ptr nonnull undef)
; CHECK-NEXT:    to label [[BB29:%.*]] unwind label [[BB30_THREAD]]
; CHECK:       bb29:
; CHECK-NEXT:    unreachable
; CHECK:       bb30.thread:
; CHECK-NEXT:    [[LPAD_THR_COMM:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT:    catch ptr @global.1
; CHECK-NEXT:    catch ptr null
; CHECK-NEXT:    br label [[BB32:%.*]]
; CHECK:       bb30:
; CHECK-NEXT:    [[LPAD_THR_COMM_SPLIT_LP:%.*]] = landingpad { ptr, i32 }
; CHECK-NEXT:    catch ptr @global.1
; CHECK-NEXT:    catch ptr null
; CHECK-NEXT:    br label [[BB32]]
; CHECK:       bb32:
; CHECK-NEXT:    unreachable
;
bb:
  invoke void @bar()
  to label %bb1 unwind label %bb3

bb1:
  invoke void @bar()
  to label %bb2 unwind label %bb4

bb2:
  invoke void @bar()
  to label %bb6 unwind label %bb17

bb3:
  %tmp = landingpad { ptr, i32 }
  catch ptr @global.1
  catch ptr null
  unreachable

bb4:
  %tmp5 = landingpad { ptr, i32 }
  catch ptr @global.1
  catch ptr null
  unreachable

bb6:
  invoke void @bar()
  to label %bb7 unwind label %bb19

bb7:
  invoke void @bar()
  to label %bb10 unwind label %bb8

bb8:
  %tmp9 = landingpad { ptr, i32 }
  cleanup
  catch ptr @global.1
  catch ptr null
  unreachable

bb10:
  %tmp11 = load ptr, ptr undef, align 8
  %tmp12 = invoke i32 %tmp11(ptr nonnull undef)
  to label %bb13 unwind label %bb21

bb13:
  invoke void @bar()
  to label %bb14 unwind label %bb23

bb14:
  %tmp15 = load ptr, ptr undef, align 8
  %tmp16 = invoke i32 %tmp15(ptr nonnull undef)
  to label %bb26 unwind label %bb23

bb17:
  %tmp18 = landingpad { ptr, i32 }
  catch ptr @global.1
  catch ptr null
  unreachable

bb19:
  %tmp20 = landingpad { ptr, i32 }
  catch ptr @global.1
  catch ptr null
  unreachable

bb21:
  %tmp22 = landingpad { ptr, i32 }
  catch ptr @global.1
  catch ptr null
  unreachable

bb23:
  %tmp24 = phi ptr [ null, %bb26 ], [ null, %bb14 ], [ undef, %bb13 ]
  %tmp25 = landingpad { ptr, i32 }
  catch ptr @global.1
  catch ptr null
  br label %bb30

bb26:
  %tmp27 = load ptr, ptr undef, align 8
  %tmp28 = invoke i32 %tmp27(ptr nonnull undef)
  to label %bb29 unwind label %bb23

bb29:
  unreachable

bb30:
  %tmp31 = icmp eq ptr %tmp24, null
  br i1 %tmp31, label %bb32, label %bb29

bb32:
  unreachable
}

declare void @bar()
